package com.timwhit;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;

public class DiskCheck {
	private static final String TEXT_TO_WRITE = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ac lectus ac lacus ullamcorper sollicitudin. Etiam et enim consequat nibh cursus consectetur sit amet ac orci. In cursus orci gravida risus semper vel pretium tortor scelerisque. Aliquam sed velit eros, vitae suscipit orci. Curabitur non lectus ut quam dapibus porttitor ultrices vel nisi. Morbi venenatis faucibus rutrum. Vivamus nec sapien sed tortor gravida congue. Nam nisl lorem, vulputate malesuada hendrerit varius, porta quis nunc. Integer lacinia faucibus mauris, a pellentesque erat commodo eget. In metus risus, gravida quis laoreet id, ultrices vitae ligula. Suspendisse fringilla libero eget libero consectetur ac pulvinar ligula sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.\n";
	private static final String TEXT_TO_READ = TEXT_TO_WRITE.substring(0, TEXT_TO_WRITE.length() - 1);
	
	public static void main(String[] args) {
		if (args != null && args.length > 0 && args[0] != null) {
			int timesToRun = 1;
			
			if (args.length > 1) {
				try {
					timesToRun = Integer.parseInt(args[1]);
					if (timesToRun == -1) {
						timesToRun = Integer.MAX_VALUE;
						System.out.println("Running forever. CTRL-C to stop.");
					} else {
						System.out.println("Running for " + timesToRun + " iterations.");
					}
				} catch (NumberFormatException e) {
					timesToRun = 1;
				}
			}
			
			for (int z = 0; z < timesToRun; z++) {
				System.out.println("Run #" + (z + 1));
				
				try {
					FileWriter fstream;
					File file = new File(args[0]);
					
					if (!file.isDirectory()) {
						System.out.println("Argument must be a directory.");
						System.exit(0);
					}
					
					if (!file.canWrite()) {
						System.out.println("Directory is not writable.");
						System.exit(0);
					}
					
					String filename = args[0] + "testFile" + System.currentTimeMillis();
					
					fstream = new FileWriter(filename);
					BufferedWriter out = new BufferedWriter(fstream);
					
					boolean write = true;
					long i = 0;
					
					System.out.println("Writing to: " + filename);
					
					DecimalFormat formatter = new DecimalFormat("###.##");
					long space = file.getUsableSpace();
					long startTime = System.currentTimeMillis();
					while (write) {
						try {
							out.write(TEXT_TO_WRITE);
							out.flush();
							i++;
							
							if (i % 20000 == 0) {
								double percent = (double)(TEXT_TO_WRITE.length() * i) / space;
								float dataWritten = (float)((i * TEXT_TO_WRITE.length()) / 1024 / 1024);
								float speed = dataWritten / ((System.currentTimeMillis() - startTime) / 1000);
								
								System.out.print(formatter.format(percent * 100) + "% - " + formatter.format(speed) + " MB/s - Data written: "
								        + formatter.format(dataWritten) + " MB                 \r");
							}
						} catch (IOException e) {
							System.out.println(e.getMessage());
							write = false;
							out.close();
							i++;
						}
					}
					
					FileInputStream fileInputStream = new FileInputStream(filename);
					
					DataInputStream in = new DataInputStream(fileInputStream);
					BufferedReader br = new BufferedReader(new InputStreamReader(in));
					
					String line;
					long j = 0;
					
					System.out.println("Reading from: " + filename);
					System.out.println("Number of lines to read: " + i);
					
					while ((line = br.readLine()) != null) {
						j++;
						if (!line.equals(TEXT_TO_READ) && j < i) {
							System.out.println("last line number read: " + j);
							System.out.println("last line read: " + line);
							throw new RuntimeException("Data read is different than what was written.");
						}
						
						if (j % 20000 == 0) {
							float f = (float)j / i;
							System.out.print(f * 100 + "\r");
						}
					}
					
					if (j == i) {
						System.out.println("Data read is the same as what was written.");
					} else {
						System.out.println("Data read is different from what was written.");
						System.out.println("Lines Written: " + i);
						System.out.println("Lines Read: " + j);
					}
					
					in.close();
					
					file = new File(filename);
					file.delete();
					
				} catch (Exception e) {
					e.printStackTrace();
					throw new RuntimeException("Error: " + e.getMessage());
				}
			}
		} else {
			System.out.println("No path argument passed");
			System.out.println("Usage: java -jar diskcheck.jar /path numberOfIterations");
			System.out.println("Pass -1 to run forever");
		}
		
		System.exit(0);
	}
}